#ifndef __QTAS_RR_H__
#define __QTAS_RR_H__

#include "quakedef.h"
#include "mtrand.h"

#define RR_Q1_SESSIONDATA_VERSION	1
#define RR_Q1_SAVESTATE_VERSION		1
#define RR_Q1_INPUTFILE_VERSION		1
#define RR_Q1_INPUTFILE_IDENTIFIER	"QTAS_Q1_INPUT___"

typedef struct
{
	int version;
	float skill;
	unsigned int initialSeed;
	int serverflags;
	float spawnparms[NUM_SPAWN_PARMS];
	char mapname[64];
} rr_q1_sessiondata_t;


// State format:
// rr_q1_savestate_t                    - Server state
// bytes                                - Input
// rr_q1_clientstate_t[sv.maxclients]   - Client states
// Variable                             - Global definitions, serializes all globals with DEF_SAVEGLOBAL bit set
// rr_q1_edictstate[sv.num_edicts]      - Base edict states
// Variable                             - Edict states for all edicts that are not free, serializes all fields from pr_fielddefs
// Area node links                      - Area node links
//
// Input files are stored in a parallel .qri file

typedef struct
{
	int version;
	int rrFrameCount;
	unsigned int rrNumInputBytes;
	mtrand_state_t rrRandomState;
	char machineId[64];					// Unique local machine ID
	unsigned int sessionHash[8];		// SHA256 of session data
	float cvSkill;						// "skill" cvar value
	double svTime;						// sv.time
	char svName[64];					// sv.name (check)
	int svMaxClients;					// sv.maxclients (check)
	int svMaxClientsLimit;				// sv.maxclientslimit (check)
	int svNumEdicts;					// sv.num_edicts
	int svNumAreaNodes;					// sv_numareanodes (check)
	int prNumGlobalDefs;				// progs->numglobaldefs (check)
	int prNumFieldDefs;					// progs->numfielddefs (check)
	float clViewAngles[3];				// cv.viewangles
} rr_q1_savestate_t;

typedef struct
{
	int edictIdx;
	char name[32];
	int colors;
	float spawnParms[NUM_SPAWN_PARMS];
} rr_q1_clientstate_t;

typedef struct
{
	int free;
	entity_state_t baseline;
	float freetime;
	int			num_leafs;
	short		leafnums[MAX_ENT_LEAFS];
} rr_q1_edictstate_t;


// Variable serialization modes:
// - ev_string: Offset into pr_strings, but that can be anything, so store as LPS and translate on deserialize
// - ev_entity: val->edict raw
// - ev_function: val->function
// - ev_field: val->_int
// - ev_void: Ignore
// - ev_float: val->_float
// - ev_vector: val->vector

// Area node link serialization:
// - Each node starts with an integer for the number of links, followed by the linked edict indexes in sequential order



typedef struct
{
	char identifier[16];
	int version;
	unsigned int numrecords;
	unsigned int headersize;
	unsigned int framesize;

	float frametime;
	unsigned int initialseed;
	unsigned int sessionhash[8];
} rr_q1_inputfile_t;

#define RR_Q1_BIT_ATTACK	1
#define RR_Q1_BIT_JUMP		2

typedef struct
{
	float viewangles[3];
	short forwardmove;
	short sidemove;
	short upmove;
	unsigned char buttonbits;
	unsigned char impulse;
} rr_q1_inputframe_t;

// Input files just store raw usercmd_t's

void RR_Init ();											// Initializes RR functions
void RR_BeginSession (char *mapname, qboolean closeInput);	// Backs up all session data to prevent any further modification and guarantee reliable server starts
unsigned int RR_Rand ();
int RR_Hex32(char *str);
float RR_RecastIToF(int i);
void RR_InitStringPool();

void RR_CloseInput_f (void);
void RR_ProcessInput (usercmd_t *ucmd);

cvar_t		rr_framelimit;
cvar_t		rr_frametime;
cvar_t		rr_timescale;
int			rr_framenumber;
int			rr_keybits;
qboolean	rr_clienthascontrol;


#endif
